#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>

#include <time.h>
#include <ctype.h>
#include <stddef.h>
#include <stdio.h>
#include <stdint.h>
#include "os_api.h"
#include "ps_api.h"
#include "dev_api.h"
#include "debug.h"
#include "sockets.h"
#include "def.h"
#include "netdb.h"
#include "socket_service.h"

#define _TASK_STACK_SIZE    (1024*1)
typedef enum
{
	DEV_LOGIN,
	DEV_HEART,
}DEV_PACKET_E;

static OSATimerRef g_s_socket0_send_heart_timer = NULL;

static void socket0_send_heart_timer_callback(void)
{
	LOG_PRINTF("send request");

	int result = socket_send(0, 13, "socket0 heart", DEV_HEART);

	if (0 != result)
	{
		LOG_PRINTF("sync result %d", result);
        
        if(g_s_socket0_send_heart_timer == NULL){
            OSATimerCreate(&g_s_socket0_send_heart_timer);
        }
        OSATimerStart(g_s_socket0_send_heart_timer, 200 * 3, 0, socket0_send_heart_timer_callback, 0);
	}
}

static void socket0_send_heart()
{
	if (g_s_socket0_send_heart_timer != NULL)
	{ 
        OSATimerDelete(g_s_socket0_send_heart_timer);
	}
	
    OSATimerCreate(&g_s_socket0_send_heart_timer);
	OSATimerStart(g_s_socket0_send_heart_timer, 200 * 3, 0, socket0_send_heart_timer_callback, 0);
}


static void socket0_event_callback(int app_id, SOCKET_EVENT_E event, socket_event_param_t param)
{
	LOG_PRINTF("[app_id %d]: %d", app_id, event);

	switch (event)
	{
	case SOCKET_EVENT_CONNECT:
		if (param.connect_result >= 0)
		{
			LOG_PRINTF("[app_id %d]: connect ok", app_id);
			socket_send(app_id, 13, "socket0 login", DEV_LOGIN);
		}
		else
		{
			LOG_PRINTF("[app_id %d]: connect fail, result %d", param.connect_result);
		}
		break;
	
	case SOCKET_EVENT_SEND:
		if (DEV_LOGIN == param.send_cnf_t.user_param)
		{
			LOG_PRINTF("[app_id %d]: send DEV_LOGIN %s", app_id, (param.send_cnf_t.result > 0) ? "OK" : "FAIL");

			if (param.send_cnf_t.result > 0)
			{
				socket0_send_heart();
			}
			else
			{

			}
		}
		else if (DEV_HEART == param.send_cnf_t.user_param)
		{
			LOG_PRINTF("[app_id %d]: send DEV_HEART %s", app_id, (param.send_cnf_t.result > 0) ? "OK" : "FAIL");

			if (param.send_cnf_t.result > 0)
			{
				socket0_send_heart();
			}
			else
			{

			}
		}
		else
		{
			/* code */
		}	
		
		break;

	case SOCKET_EVENT_RECEIVE:
		LOG_PRINTF("[app_id %d]: receive data len %d", app_id, param.recv_ind_t.len);
		break;

	default:
		break;
	}	
}


static OSATaskRef g_s_socket1_send_heart_task_handle      = NULL;
static void*  g_s_socket1_send_heart_stack = NULL;


static OSAFlagRef g_s_socket1_send_heart_semaphore_handle = NULL;
UINT32  g_s_socket1_send_heart_semaphore_flag = 0x01;


static void socket1_send_heart_task_proc(void *arg)
{
	int result;

    OSAFlagCreate(&g_s_socket1_send_heart_semaphore_handle);

	while (1)
	{
		LOG_PRINTF("send request");

		result = socket_send(1, 13, "socket1 heart", DEV_HEART);

		if (0 == result)
		{
            OSAFlagWait(g_s_socket1_send_heart_semaphore_handle, 0x01, OSA_FLAG_OR_CLEAR,&g_s_socket1_send_heart_semaphore_flag,OS_SUSPEND);
		}
		else
		{
			LOG_PRINTF("sync result %d", result);
		}		

		OSATaskSleep(200 * 3);
	}
	
}

static void socket1_send_heart()
{
	if (g_s_socket1_send_heart_task_handle == NULL)
	{
        g_s_socket1_send_heart_stack = (void *)malloc(_TASK_STACK_SIZE);
        OSATaskCreate(&g_s_socket1_send_heart_task_handle,g_s_socket1_send_heart_stack,_TASK_STACK_SIZE,81,"socket1_send_heart", socket1_send_heart_task_proc, NULL);
	}
}


static void socket1_event_callback(int app_id, SOCKET_EVENT_E event, socket_event_param_t param)
{
	LOG_PRINTF("[app_id %d]: %d", app_id, event);

	switch (event)
	{
	case SOCKET_EVENT_CONNECT:
		if (param.connect_result >= 0)
		{
			LOG_PRINTF("[app_id %d]: connect ok", app_id);
			socket_send(app_id, 13, "socket1 login", DEV_LOGIN);
		}
		else
		{
			LOG_PRINTF("[app_id %d]: connect fail, result %d", param.connect_result);
		}
		break;
	
	case SOCKET_EVENT_SEND:
		if (DEV_LOGIN == param.send_cnf_t.user_param)
		{
			LOG_PRINTF("[app_id %d]: send DEV_LOGIN %s", app_id, (param.send_cnf_t.result > 0) ? "OK" : "FAIL");

			if (param.send_cnf_t.result > 0)
			{
				socket1_send_heart();
			}
			else
			{

			}
		}
		else if (DEV_HEART == param.send_cnf_t.user_param)
		{
			LOG_PRINTF("[app_id %d]: send DEV_HEART %s", app_id, (param.send_cnf_t.result > 0) ? "OK" : "FAIL");

            OSAFlagSet(g_s_socket1_send_heart_semaphore_handle ,0x01, OSA_FLAG_OR);
		}
		else
		{
			/* code */
		}	
		
		break;

	case SOCKET_EVENT_RECEIVE:
		LOG_PRINTF("[app_id %d]: receive data len %d", app_id, param.recv_ind_t.len);
		break;

	default:
		break;
	}	
}

void test_service_init(void)
{
	socket_connect(0, 0, "122.51.209.56", 5858, socket0_event_callback);
	socket_connect(1, 0, "122.51.209.56", 5859, socket1_event_callback);
}

